From e1bc13a960bab6c8efd73200138efeb31a5aa35f Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 9 Mar 2007 11:11:59 +0000 Subject: [PATCH] xm: New command 'debug-keys' to inject debug-key events into Xen. Signed-off-by: Keir Fraser --- tools/libxc/xc_misc.c | 19 ++++++++++++++++ tools/libxc/xenctrl.h | 2 ++ tools/python/xen/lowlevel/xc/xc.c | 24 ++++++++++++++++++++ tools/python/xen/xend/XendNode.py | 6 +++++ tools/python/xen/xend/server/XMLRPCServer.py | 2 +- tools/python/xen/xm/main.py | 8 ++++++- xen/common/keyhandler.c | 2 +- xen/common/sysctl.c | 15 ++++++++++++ xen/include/public/sysctl.h | 13 +++++++++++ 9 files changed, 88 insertions(+), 3 deletions(-) diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index b2a648528a..987eb0eb13 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -33,6 +33,25 @@ int xc_readconsolering(int xc_handle, return ret; } +int xc_send_debug_keys(int xc_handle, char *keys) +{ + int ret, len = strlen(keys); + DECLARE_SYSCTL; + + sysctl.cmd = XEN_SYSCTL_debug_keys; + set_xen_guest_handle(sysctl.u.debug_keys.keys, keys); + sysctl.u.debug_keys.nr_keys = len; + + if ( (ret = lock_pages(keys, len)) != 0 ) + return ret; + + ret = do_sysctl(xc_handle, &sysctl); + + unlock_pages(keys, len); + + return ret; +} + int xc_physinfo(int xc_handle, xc_physinfo_t *put_info) { diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 96ba314503..4b346a74f0 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -467,6 +467,8 @@ int xc_readconsolering(int xc_handle, unsigned int *pnr_chars, int clear); +int xc_send_debug_keys(int xc_handle, char *keys); + typedef xen_sysctl_physinfo_t xc_physinfo_t; int xc_physinfo(int xc_handle, xc_physinfo_t *info); diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 7da0288cbd..804adc3104 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -1007,6 +1007,24 @@ static PyObject *pyxc_domain_send_trigger(XcObject *self, return zero; } +static PyObject *pyxc_send_debug_keys(XcObject *self, + PyObject *args, + PyObject *kwds) +{ + char *keys; + + static char *kwd_list[] = { "keys", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "s", kwd_list, &keys) ) + return NULL; + + if ( xc_send_debug_keys(self->xc_handle, keys) != 0 ) + return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; +} + static PyObject *dom_op(XcObject *self, PyObject *args, int (*fn)(int, uint32_t)) { @@ -1420,6 +1438,12 @@ static PyMethodDef pyxc_methods[] = { " vcpu [int]: VCPU to be sent trigger.\n" "Returns: [int] 0 on success; -1 on error.\n" }, + { "send_debug_keys", + (PyCFunction)pyxc_send_debug_keys, + METH_VARARGS | METH_KEYWORDS, "\n" + "Inject debug keys into Xen.\n" + " keys [str]: String of keys to inject.\n" }, + #ifdef __powerpc__ { "arch_alloc_real_mode_area", (PyCFunction)pyxc_alloc_real_mode_area, diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index 9d2a70dd9e..5976d80f39 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -453,6 +453,12 @@ class XendNode: return pif.network raise Exception('Bridge %s is not connected to a network' % bridge) + # + # Debug keys. + # + + def send_debug_keys(self, keys): + return self.xc.send_debug_keys(keys) # # Getting host information. diff --git a/tools/python/xen/xend/server/XMLRPCServer.py b/tools/python/xen/xend/server/XMLRPCServer.py index 7c3a2a1a9d..ed07811ff6 100644 --- a/tools/python/xen/xend/server/XMLRPCServer.py +++ b/tools/python/xen/xend/server/XMLRPCServer.py @@ -157,7 +157,7 @@ class XMLRPCServer: self.server.register_function(fn, "xend.domain.%s" % name[7:]) # Functions in XendNode and XendDmesg - for type, lst, n in [(XendNode, ['info'], 'node'), + for type, lst, n in [(XendNode, ['info', 'send_debug_keys'], 'node'), (XendDmesg, ['info', 'clear'], 'node.dmesg')]: inst = type.instance() for name in lst: diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 7075e95444..8fcc2bc525 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -133,6 +133,7 @@ SUBCOMMAND_HELP = { 'sched-credit': ('[-d [-w[=WEIGHT]|-c[=CAP]]]', 'Get/set credit scheduler parameters.'), 'sysrq' : (' ', 'Send a sysrq to a domain.'), + 'debug-keys' : ('', 'Send debug keys to Xen.'), 'trigger' : (' []', 'Send a trigger to a domain.'), 'vcpu-list' : ('[]', @@ -260,7 +261,6 @@ common_commands = [ "shutdown", "start", "suspend", - "trigger", "top", "unpause", "uptime", @@ -300,6 +300,7 @@ domain_commands = [ ] host_commands = [ + "debug-keys", "dmesg", "info", "log", @@ -1395,6 +1396,10 @@ def xm_trigger(args): server.xend.domain.send_trigger(dom, trigger, vcpu) +def xm_debug_keys(args): + arg_check(args, "debug-keys", 1) + server.xend.node.send_debug_keys(str(args[0])) + def xm_top(args): arg_check(args, "top", 0) @@ -1738,6 +1743,7 @@ commands = { "pause": xm_pause, "unpause": xm_unpause, # host commands + "debug-keys": xm_debug_keys, "dmesg": xm_dmesg, "info": xm_info, "log": xm_log, diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index b99d396399..da92b6fded 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -47,7 +47,7 @@ void handle_keypress(unsigned char key, struct cpu_user_regs *regs) { irq_keyhandler_t *h; - if ( key_table[key].flags & KEYHANDLER_IRQ_CALLBACK ) + if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) ) { console_start_log_everything(); if ( (h = key_table[key].u.irq_handler) != NULL ) diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c index 789e643ff2..0cba2c1164 100644 --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -121,6 +122,20 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) break; #endif + case XEN_SYSCTL_debug_keys: + { + char c; + uint32_t i; + + for ( i = 0; i < op->u.debug_keys.nr_keys; i++ ) + { + if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) ) + return -EFAULT; + handle_keypress(c, guest_cpu_user_regs()); + } + } + break; + default: ret = arch_do_sysctl(op, u_sysctl); break; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index dcd7ee7d26..e18d7243f6 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -140,6 +140,18 @@ struct xen_sysctl_getdomaininfolist { typedef struct xen_sysctl_getdomaininfolist xen_sysctl_getdomaininfolist_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_getdomaininfolist_t); +/* + * Inject debug keys into Xen. + */ +#define XEN_SYSCTL_debug_keys 7 +struct xen_sysctl_debug_keys { + /* IN variables. */ + XEN_GUEST_HANDLE_64(char) keys; + uint32_t nr_keys; +}; +typedef struct xen_sysctl_debug_keys xen_sysctl_debug_keys_t; +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_debug_keys_t); + struct xen_sysctl { uint32_t cmd; uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */ @@ -150,6 +162,7 @@ struct xen_sysctl { struct xen_sysctl_sched_id sched_id; struct xen_sysctl_perfc_op perfc_op; struct xen_sysctl_getdomaininfolist getdomaininfolist; + struct xen_sysctl_debug_keys debug_keys; uint8_t pad[128]; } u; }; -- 2.30.2